package com.wksc.framework.impexp.writer;

import java.io.File;
import java.io.IOException;
import java.util.List;

import com.wksc.framework.impexp.bean.ExcelHeader;
import com.wksc.framework.impexp.util.ExcelTool;
import jxl.Workbook;
import jxl.format.CellFormat;
import jxl.format.VerticalAlignment;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCell;
import jxl.write.WritableCellFormat;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

/**
 * <p> Title(文件名): ${file_name} </p>
 * <p> Description(描述): ${todo} </p>
 * <p> Copyright(版权): Copyright (c) ${year} </p>
 * <p> Company(公司): 成都四方信息技术有限公司 </p>
 * <p> CreateTime(生成日期)：11-11-3下午2:57 </p>
 *
 * @author wanglei
 * @version ${project_name}
 */
public class XlsWriter extends Writer {
    /**
     * Excel文件
     */
    protected WritableWorkbook writableBook;
    /**
     * EXCEL工作表
     */
    protected WritableSheet writableSheet;
    
	private Object objExcelConflate;
	
	/**
     * 初始化Excel文件,
     * 假如createFile为true则表示需要创建新的Excel文件
     * 若CreateFile为false则表示只需要获取之前的文件进行追加内容
     *
     * @throws java.io.IOException
     * @throws BiffException
     */
	@Override
	public void initWriter(File file, boolean createFile) throws IOException, BiffException {
		this.file = file;
		this.createFile = createFile;
		if (createFile) {
            createNewSheet();
        } else {
            getSheet();
        }
	}

    /**
     * 根据文件创建新的Excel文件以及可写入的sheet
     *
     * @throws java.io.IOException
     */
    private void createNewSheet() throws IOException {
        writableBook = Workbook.createWorkbook(file);
        writableSheet = writableBook.createSheet("sheet1", 0);
    }

    /**
     * 从获取已有的Excel文件和可写入的sheet
     *
     * @throws BiffException
     * @throws java.io.IOException
     */
    private void getSheet() throws BiffException, IOException {
        Workbook workbook = Workbook.getWorkbook(file);
        writableBook = Workbook.createWorkbook(file, workbook);
        writableSheet = writableBook.getSheet(0);
    }

    /**
     * 将整行数据写入指定的位置
     *
     *
     * @param data   待写入数据
     * @param rowNum 待写入的行号
     * @return 成功写入的列数
     * @throws WriteException
     */
    @Override
    public boolean writeByRow(Object[] data, int rowNum) throws WriteException, IOException {
        if (null != data) {
                for (int i = 0; i < data.length; i++) {
                	if (data[i] instanceof ExcelHeader) {
                		 ExcelHeader t = (ExcelHeader) data[i];
         				writableSheet.addCell(new Label(t.getColInex(),  t.getRowIndex(), t.getContent()));
         				if (t.getColSpan() > 0 || t.getRowSpan() > 0) {
         					writableSheet.mergeCells(t.getColInex(), t.getRowIndex(), t
         							.getColInex()
         							+ t.getColSpan(), t.getRowIndex() + t.getRowSpan());
         				}
                	} else {
                		WritableCell cell = new Label(i, rowNum, (String)data[i]);
                		writableSheet.addCell(cell);
                	}
                }
        }
        return true;
    }

    /**
     * 写入单行数据
     *
     * @param data  待写入的数据
     * @param rowNum  行号
     * @param colIndex 哪些列写入
     * @return   该列是否成功写入
     * @throws WriteException
     */
    @Override
    public boolean writeByRow(Object[] data, int rowNum, Integer[] colIndex) throws WriteException {
        if (null != data) {
            for(int i = 0; i < colIndex.length; i++){
                WritableCell cell = new Label(i, rowNum, (String)data[colIndex[i]]);
                writableSheet.addCell(cell);
            }
        }
        return true;
    }
    
    /**
	 * 带单元格格式的添加
	 * 
	 * @date 2010-6-28
	 * @author yanliang
	 * @param obj
	 * @param col
	 * @param row
	 * @param align
	 * @throws WriteException
	 */
	protected void addCellVertiAlign(Object obj, int col, int row,
			VerticalAlignment align) throws WriteException {
		WritableCellFormat format = new WritableCellFormat();
		format.setVerticalAlignment(align);
		WritableCell cell = new Label(col, row, (String)obj);
		// 设置居中显示
		cell.setCellFormat(format);
		writableSheet.addCell(cell);
		format = null;
	}

    /**
     * 适用于普通数据的批量写入
     */
    @Override
    public int writeByRows(List<?> data, int startLine, Integer[] rowIndex) throws WriteException {
        int succNum = 0;
        for(int i = 0; i < data.size(); i++){
            if(writeByRow((Object[])data.get(i), startLine++, rowIndex)){
                 succNum++;
            }
        }
        return succNum;
    }

    /**
     * 写导入文件错误信息用
     *
     * @param data 待写入的错误信息
     * @return 成功写入的条数
     * @throws WriteException
     * @throws java.io.IOException
     */
    @Override
    public int writeByCol(int colNum, List<String> data) throws IOException, WriteException {   //Tested
        int succNum = 0;
        //错误信息的格式
        CellFormat errFormat = ExcelTool.getRedFont();
        //单个单元格
        Label label;

		for (int i = 0; i < data.size(); i++) {
			label = new Label(colNum, i, data.get(i), errFormat);
			try {
				// 将Cell添加至sheet
				writableSheet.addCell(label);
				succNum++;
			} catch (WriteException e) {
				// 某一个若有写入异常,只捕获,不处理
			}
		}
		return succNum;
    }

    /**
     * 完成写入文件时进行关闭等操作
     */
    @Override
    public void close() throws IOException, WriteException {
          write();
    }

    /**
     * 将内容写入Excel的方法
     * @throws java.io.IOException
     * @throws WriteException
     */
    private void write() throws IOException, WriteException {
        try {
            writableBook.write();
        } finally {
            writableBook.close();
        }
    }

	@Override
	public int writeByRows(List<?> data, int startLine)
			throws RowsExceededException, WriteException, IOException {
		int succNum = 0;
		for(int i = 0; i < data.size(); i++){
			if(writeByRow((Object[]) data.get(i), startLine++)){
				succNum = succNum + 1;
			}
		}
		return succNum;
	}

	public Object getObjExcelConflate() {
		return objExcelConflate;
	}

	/**
	 * 方法描述：设置合并单元格需要的参数
	 *
	 * @creator wanglei
	 * @param objExcelConflate
	 */
	public void setObjExcelConflate(Object objExcelConflate) {
		this.objExcelConflate = objExcelConflate;
	}
}
